package com.hskn.hss.module.depart.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hskn.hss.core.page.TableDataInfo;
import com.hskn.hss.core.utils.LoginUtils;
import com.hskn.hss.entity.AjaxResult;
import com.hskn.hss.entity.TreeEntity;
import com.hskn.hss.exception.HssException;
import com.hskn.hss.module.alarmcar.entity.AlarmCar;
import com.hskn.hss.module.alarmcar.mapper.AlarmCarMapper;
import com.hskn.hss.module.alarmperson.entity.AlarmPerson;
import com.hskn.hss.module.alarmperson.mapper.AlarmPersonMapper;
import com.hskn.hss.module.alarmsheshi.entity.AlarmSheshi;
import com.hskn.hss.module.alarmsheshi.mapper.AlarmSheshiMapper;
import com.hskn.hss.module.depart.entity.SysDepart;
import com.hskn.hss.module.depart.entity.SysDepartCharts;
import com.hskn.hss.module.depart.mapper.SysDepartMapper;
import com.hskn.hss.module.depart.service.ISysDepartService;
import com.hskn.hss.module.oilDevice.domain.StateOilDevice;
import com.hskn.hss.module.tlemployee.entity.TlEmployee;
import com.hskn.hss.module.tlemployee.mapper.TlEmployeeMapper;
import com.hskn.hss.module.user.entity.User;
import com.hskn.hss.module.user.mapper.UserMapper;
import com.hskn.hss.module.userdepart.service.ISysUserDepartService;
import com.hskn.hss.utils.*;
import org.aspectj.lang.annotation.AfterReturning;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 组织机构表 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2021-04-30
 */
@Service
public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart> implements ISysDepartService {
    @Resource
    SysDepartMapper sysDepartMapper;
    @Autowired
    ISysUserDepartService sysUserDepartService;
    @Resource
    TlEmployeeMapper tlEmployeeMapper;
    @Resource
    UserMapper userMapper;
    @Resource
    AlarmPersonMapper alarmPersonMapper;
    @Resource
    AlarmCarMapper alarmCarMapper;
    @Resource
    AlarmSheshiMapper alarmSheshiMapper;

    @Override
    public AjaxResult insert(JSONObject params) throws HssException {

        String username = LoginUtils.getUser().getAccount();
        SysDepart sysDepart = params.getObject("data", SysDepart.class);
        sysDepart.setId(StringUtils.uuid());
//        Map map = new HashMap();
//        map.put("org_code", sysDepart.getOrgCode());
//        map.put("del_flag", "0");
//
//        List<SysDepart> sysDeparts = sysDepartMapper.selectByMap(map);
//        if (!sysDeparts.isEmpty()) {
//            return AjaxResult.fail("部门编码重复");
//        }

        String struids = GetStructureByParentId(sysDepart.getParentId());
        if (struids != null && !struids.equals("")) {
            struids = struids + sysDepart.getParentId() + "@";
            sysDepart.setStructureids(struids);
        } else {
            sysDepart.setStructureids(sysDepart.getParentId().equals("") || sysDepart.getParentId() == null ? "@" : sysDepart.getParentId());
        }

        sysDepart.setCreateBy(username);
        sysDepart.setCreateTime(new Date());
        int i = sysDepartMapper.insert(sysDepart);
        boolean flag = i > 0;

        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public AjaxResult deleteByid(JSONObject params) throws HssException {
        String id = params.getString("id");
        SysDepart sysDepart = sysDepartMapper.selectById(id);
        sysDepart.setDelFlag("1");
        int i = sysDepartMapper.updateById(sysDepart);
        boolean flag = i > 0;
        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public AjaxResult deletebatchbyid(SysDepart sysDepart) throws HssException {

        sysDepart.setDelFlag("1");
        UpdateWrapper<SysDepart> sysDepartUpdateWrapper = new UpdateWrapper<>();
        sysDepartUpdateWrapper.lambda().in(SysDepart::getId, sysDepart.getIds());

        int i = sysDepartMapper.update(sysDepart, sysDepartUpdateWrapper);

        boolean flag = i > 0;
        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public AjaxResult update(JSONObject params) throws HssException {

        String username = LoginUtils.getUser().getAccount();
        SysDepart sysDepart = params.getObject("data", SysDepart.class);

//        Map map = new HashMap();
//        map.put("org_code", sysDepart.getOrgCode());
//        List<SysDepart> sysDeparts = sysDepartMapper.selectByMap(map);
//        if (!sysDeparts.isEmpty() && sysDeparts.get(0).getId() != sysDepart.getId()) {
//            return AjaxResult.fail("部门编码重复");
//        }

        String struids = GetStructureByParentId(sysDepart.getParentId());
        if (struids != null && !struids.equals("")) {
            struids = struids + sysDepart.getParentId() + "@";
            sysDepart.setStructureids(struids);
        } else {
            sysDepart.setStructureids(sysDepart.getParentId().equals("") || sysDepart.getParentId() == null ? "@" : sysDepart.getParentId());
        }

        sysDepart.setUpdateBy(username);
        sysDepart.setUpdateTime(new Date());
        int i = sysDepartMapper.updateById(sysDepart);
        boolean flag = i > 0;
        if (flag) {
            return AjaxResult.success();
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public SysDepart getInfoById(JSONObject params) throws HssException {
        String id = params.getString("id");
        SysDepart sysDepart = sysDepartMapper.getDeptIdById(id);
        //用户档案关联手机号查询
        if(StringUtils.isNotEmpty(sysDepart.getPrincipalUid())){
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(User::getUid,sysDepart.getPrincipalUid());
            List<User> users = userMapper.selectList(queryWrapper);
            sysDepart.setUserPhone(users.get(0).getPhone());
        }
        return sysDepart;
    }

    @Override
    public JSONObject getList(JSONObject params) throws HssException {
        Long page = StringUtils.isEmpty(params.getLong("page")) ? 1 : params.getLong("page");
        Long size = StringUtils.isEmpty(params.getLong("size")) ? 10 : params.getLong("size");
        JSONObject json = new JSONObject();

        Map<String, Object> map = new HashMap();
//        String pidsStr = params.getString("parentid");
//        if (StringUtils.isNotEmpty(pidsStr)) {
//            String[] pids = pidsStr.split(",");
//            if (pids.length > 0) {
//                map.put("parent_id", Arrays.asList(pids));
////                map.put("parent_id", pids[0]);
//            }
//        }
        map.put("parent_id", params.getString("parentid"));
        map.put("org_code", params.getString("orgcode"));
        map.put("org_type", params.getString("orgtype"));
        map.put("status", params.getString("status"));
        map.put("del_flag", params.getString("delflag"));


        Page<SysDepart> deptPage = new Page<>(page, size, true);
        IPage<SysDepart> iPage = sysDepartMapper.listDeptCascade(deptPage, map);
        json.put("total", iPage.getTotal());
        json.put("size", iPage.getSize());
        json.put("pages", iPage.getPages());
        json.put("current", iPage.getCurrent());
        List<SysDepart> sysDepartList = iPage.getRecords();
        for (SysDepart sysDepart : sysDepartList) {
            List<TlEmployee> tlEmployeeList = tlEmployeeMapper.getEmployeeByDepartId(sysDepart.getId());
            User user = userMapper.selectById(sysDepart.getPrincipalUid());
            if (null != user) {
                sysDepart.setPrincipalName(user.getName());
            }
            sysDepart.setTlEmployeeList(tlEmployeeList);
        }
        json.put("depart", sysDepartList);
        return json;
    }

    @Override
    public List getdDeptIdByParentId(String parentid) {
        return sysDepartMapper.getdDeptIdByParentId(parentid);
    }

    @Override
    public List<TreeEntity> getTreeList() {
        List treeList = sysDepartMapper.getTreeList();
        return TreeUtil.RecursiveAddress(treeList);
    }

    @Override
    public List getAppUserList() {
        List<Map> deptlist = sysDepartMapper.getAppUserList();

//        for(Map dept :deptlist){
//            Map param = new HashMap();
//            param.put("deptid",dept.get("id"));
//            List bodylist = sysDepartMapper.getAppUserListByDept(param);
//        }

        Map param = new HashMap();
        List bodylist = sysDepartMapper.getAppUserListByDept(param);

        Iterator<Map> it = deptlist.iterator();
        Iterator<Map> body = bodylist.iterator();
        while (it.hasNext()) {
            Map dept = it.next();
            List childlist = new ArrayList();
            body = bodylist.listIterator(1);
            while (body.hasNext()) {
                Map bodymap = body.next();
                if (bodymap.get("depid").equals(dept.get("id"))) {
                    childlist.add(bodymap);
                    body.remove();
                }
            }
            if (childlist.isEmpty()) {
                it.remove();
            } else {
                dept.put("body", childlist);
            }

        }
        return deptlist;
    }

    @Override
    public List getAppUserListBySearch(JSONObject params) {
        Map map = new HashMap();
        map.put("name", params.get("name"));
        List userlist = sysDepartMapper.getAppUserListBySearch(map);
        return userlist;
    }

    @Override
    public String getLeaderUids() {

        String uid = LoginUtils.getUser().getUid();
        List<String> lids = new ArrayList<>();
        String depid = sysUserDepartService.getDeptidByUid(uid);
        SysDepart sysDepart = sysDepartMapper.selectById(depid);
        if (StringUtils.isNotEmpty(sysDepart)) {
            if (StringUtils.isNotEmpty(sysDepart.getPrincipalUid())) {
                lids.add(sysDepart.getPrincipalUid());
            }
            if (StringUtils.isNotEmpty(sysDepart.getParentId())) {
                SysDepart sysDepart1 = sysDepartMapper.selectById(sysDepart.getParentId());
                if (StringUtils.isNotEmpty(sysDepart1) && StringUtils.isNotEmpty(sysDepart1.getPrincipalUid())) {
                    lids.add(sysDepart1.getPrincipalUid());
                }
            }
        }
        return String.join(",", lids);
    }

    public String GetStructureByParentId(String parentid) {
        QueryWrapper<SysDepart> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysDepart::getId, parentid);
        SysDepart sysDepart = sysDepartMapper.selectOne(queryWrapper);
        return sysDepart == null ? null : sysDepart.getStructureids();
    }

    @Override
    public JSONObject collectList(JSONObject params) throws HssException {

        String uid = LoginUtils.getUser().getUid();
        JSONObject res = new JSONObject();
        Long page = (StringUtils.isEmpty(params.getLong("page")) || params.getLong("page") == 0) ? 1 : params.getLong("page");
        Long size = (StringUtils.isEmpty(params.getLong("size")) || params.getLong("size") == 0) ? 10 : params.getLong("size");
        params.put("offset", (page - 1) * size);
        params.put("limit", size);
        List<Map<String, Object>> list = sysDepartMapper.collectList(params);
        long count = sysDepartMapper.collectListCount(params);
        res.put("list", list);
        res.put("total", count);
        res.put("current", page);
        res.put("pages", (int) Math.ceil(count / size));
        res.put("size", list.size());
        return res;
    }

    @Override
    public AjaxResult selectDepartAlarmCharsTale(Integer pageNum, Integer pageSize, SysDepart depart) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        QueryWrapper<AlarmPerson> alarmPersonQueryWrapper = new QueryWrapper<>();
        QueryWrapper<AlarmCar> alarmCarQueryWrapper = new QueryWrapper<>();
        QueryWrapper<AlarmSheshi> alarmSheshiQueryWrapper = new QueryWrapper<>();
        QueryWrapper<SysDepart> departQueryWrapper = new QueryWrapper<>();
        List<SysDepart> departList = new ArrayList<>();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(depart.getId())) {
            alarmPersonQueryWrapper.lambda().eq(AlarmPerson::getDepId, depart.getId());
        }
        departList = sysDepartMapper.selectList(departQueryWrapper);
        if (depart.getStartDate() != null && depart.getEndDate() != null) {
            alarmPersonQueryWrapper.lambda().between(AlarmPerson::getCreateTime, depart.getStartDate(), depart.getEndDate());
            alarmCarQueryWrapper.lambda().between(AlarmCar::getCreateTime, depart.getStartDate(), depart.getEndDate());
            alarmSheshiQueryWrapper.lambda().between(AlarmSheshi::getCreateTime, depart.getStartDate(), depart.getEndDate());
        } else {
            alarmPersonQueryWrapper.lambda().between(AlarmPerson::getCreateTime, Tools.getFristDay(depart.getCreateTime()), Tools.getLastDay(depart.getCreateTime()));
            alarmCarQueryWrapper.lambda().between(AlarmCar::getCreateTime, Tools.getFristDay(depart.getCreateTime()), Tools.getLastDay(depart.getCreateTime()));
            alarmSheshiQueryWrapper.lambda().between(AlarmSheshi::getCreateTime, Tools.getFristDay(depart.getCreateTime()), Tools.getLastDay(depart.getCreateTime()));
        }

        if (org.apache.commons.lang3.StringUtils.isNotBlank(depart.getOrgType())) {
            departQueryWrapper.lambda().eq(SysDepart::getOrgType, depart.getOrgType());
            departList = sysDepartMapper.selectList(departQueryWrapper);
            Map<String, SysDepart> sysDepartMap = GroupingByUtils.getGroupingForMapEntity(departList, SysDepart::getId,
                    Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
            alarmPersonQueryWrapper.lambda().in(AlarmPerson::getDepId, sysDepartMap.keySet());
            alarmCarQueryWrapper.lambda().in(AlarmCar::getDepId, sysDepartMap.keySet());
            alarmSheshiQueryWrapper.lambda().in(AlarmSheshi::getDepId, sysDepartMap.keySet());
        }
        List<AlarmPerson> alarmPersonList = alarmPersonMapper.selectList(alarmPersonQueryWrapper);
        List<AlarmCar> alarmCarList = alarmCarMapper.selectList(alarmCarQueryWrapper);
        List<AlarmSheshi> alarmSheshiList = alarmSheshiMapper.selectList(alarmSheshiQueryWrapper);
        Map<String, List<AlarmPerson>> alarmPersonMap = GroupingByUtils.getGroupingForMapList(
                alarmPersonList, AlarmPerson::getDepId
        );
        Map<String, List<AlarmCar>> alarmCarMap = GroupingByUtils.getGroupingForMapList(
                alarmCarList, AlarmCar::getDepId
        );
        Map<String, List<AlarmSheshi>> alarmSheshiMap = GroupingByUtils.getGroupingForMapList(
                alarmSheshiList, AlarmSheshi::getDepId
        );
        List<SysDepartCharts> resultList = new ArrayList<>();
        for (SysDepart d : departList) {
            SysDepartCharts sysDepartCharts = new SysDepartCharts();
            sysDepartCharts.setId(d.getId());
            sysDepartCharts.setDepartName(d.getDepartName());
            sysDepartCharts.setOrgType(d.getOrgType());
            if (alarmPersonMap.containsKey(d.getId())) {
                sysDepartCharts.setPersonAlarmCount(alarmPersonMap.get(d.getId()).size());
            } else {
                sysDepartCharts.setPersonAlarmCount(0);
            }
            if (alarmCarMap.containsKey(d.getId())) {
                sysDepartCharts.setCarAlarmCount(alarmCarMap.get(d.getId()).size());
            } else {
                sysDepartCharts.setCarAlarmCount(0);
            }
            if (alarmSheshiMap.containsKey(d.getId())) {
                sysDepartCharts.setSheshiAlarmCount(alarmSheshiMap.get(d.getId()).size());
            } else {
                sysDepartCharts.setSheshiAlarmCount(0);
            }
            resultList.add(sysDepartCharts);
        }
        PageInfoConvent<SysDepartCharts> departChartsPageInfoConvent = null;
        TableDataInfo tableDataInfo = new TableDataInfo();
        if (pageNum != null && pageSize != null) {
            departChartsPageInfoConvent = new PageInfoConvent<>(pageNum, pageSize, resultList);
            tableDataInfo = new TableDataInfo(departChartsPageInfoConvent.getList(), resultList.size());
        }
        return AjaxResult.success(tableDataInfo);

    }

    @Override
    public AjaxResult selectDepartAlarmChars(SysDepart depart) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        List<String> dateList = new ArrayList<>();
        if (depart.getStartDate() != null && depart.getEndDate() != null) {
            dateList = Tools.getBetweenDate(format.format(depart.getStartDate()), format.format(depart.getEndDate()));
        } else {
            dateList = Tools.getDayListOfMonthByDate(depart.getCreateTime() == null ? new Date() : depart.getCreateTime());
        }
        if (depart.getOrgType() != null) {
            QueryWrapper<SysDepart> departQueryWrapper = new QueryWrapper<>();
            departQueryWrapper.lambda().eq(SysDepart::getOrgType, depart.getOrgType());
            List<SysDepart> departList = sysDepartMapper.selectList(departQueryWrapper);
            Map<String, SysDepart> depMap = GroupingByUtils.getGroupingForMapEntity(departList, SysDepart::getId
                    , Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
            if (!depMap.keySet().isEmpty()) {
                depart.setIds(new ArrayList<>(depMap.keySet()));
            }
        }
        List<SysDepartCharts> personAlarmList = alarmPersonMapper.selectAlarmPersonForDepart(depart);
        List<SysDepartCharts> carAlarmList = alarmCarMapper.selectAlarmCarForDepart(depart);
        List<SysDepartCharts> sheshiAlarmList = alarmSheshiMapper.selectAlarmsheshiForDepart(depart);
        Map<String, SysDepartCharts> pMap = GroupingByUtils.getGroupingForMapEntity(personAlarmList,
                SysDepartCharts::getCreateTime, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        Map<String, SysDepartCharts> cMap = GroupingByUtils.getGroupingForMapEntity(carAlarmList,
                SysDepartCharts::getCreateTime, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        Map<String, SysDepartCharts> shishiMap = GroupingByUtils.getGroupingForMapEntity(sheshiAlarmList,
                SysDepartCharts::getCreateTime, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        Integer sum = 0;
        List<Object> res = new ArrayList<>();
        List<List<Object>> resList = new ArrayList<>();
        for (String date : dateList) {
            res.add(date);
            if (pMap.containsKey(date)) {
                sum += pMap.get(date).getPersonAlarmCount();
            }
            if (cMap.containsKey(date)) {
                sum += cMap.get(date).getCarAlarmCount();
            }
            if (shishiMap.containsKey(date)) {
                sum += shishiMap.get(date).getSheshiAlarmCount();
            }
            res.add(sum);
            resList.add(res);
            res = new ArrayList<>();
            sum = 0;
        }
        for (List<Object> res1 : resList) {
            if (pMap.containsKey(res1.get(0))) {
                res1.add(pMap.get(res1.get(0)).getPersonAlarmCount() == null ? 0 : pMap.get(res1.get(0)).getPersonAlarmCount());
            } else {
                res1.add(0);
            }
            if (cMap.containsKey(res1.get(0))) {
                res1.add(cMap.get(res1.get(0)).getCarAlarmCount() == null ? 0 : cMap.get(res1.get(0)).getCarAlarmCount());
            } else {
                res1.add(0);
            }
            if (shishiMap.containsKey(res1.get(0))) {
                res1.add(shishiMap.get(res1.get(0)).getSheshiAlarmCount() == null ? 0 : shishiMap.get(res1.get(0)).getSheshiAlarmCount());
            } else {
                res1.add(0);
            }
        }
        return AjaxResult.success(resList);

    }

    @Override
    public Map<String, SysDepart> getDepartMap(QueryWrapper<SysDepart> departQueryWrapper) {
        departQueryWrapper.lambda().eq(SysDepart::getDelFlag,0);
        List<SysDepart> departList = sysDepartMapper.selectList(departQueryWrapper);
        Map<String, SysDepart> departMap = new HashMap<>();
        if (!departList.isEmpty()) {
            departMap = GroupingByUtils.getGroupingForMapEntity(departList, SysDepart::getId, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        return departMap;
    }

    /**
     * 获取部门所有的子节点ID
     * @param id
     * @return
     */
    @Override
    public List<String> getChildIdsByIId(String id) {
        QueryWrapper queryWrapper = new QueryWrapper();
        List<SysDepart> sysDepartList = sysDepartMapper.selectList(queryWrapper);
        Map<String, List<String>> childListMap = new HashMap<>();
        sysDepartList.forEach(t -> {
            childListMap.put(t.getId(), new ArrayList<>());
            for (SysDepart depart : sysDepartList) {
                if (depart.getParentId().equals(t.getId())) {
                    childListMap.get(t.getId()).add(depart.getId());
                }
            }
        });
        return buildChildIdsById(id, childListMap);
    }


    private List<String> buildChildIdsById(String id, Map<String, List<String>> childListMap) {
        // 返回一個部門id下左右的子子孫孫部門id集合，不含自己
        List<String> result = new ArrayList<>();
        if (childListMap.get(id) == null || childListMap.get(id).size() == 0) {
            result.add(id);
            return result;
        } else {
            for (String childId : childListMap.get(id)) {
                for (String childId2 : buildChildIdsById(childId, childListMap)) {
                    result.add(childId2);
                }
            }
            result.add(id);
            result = result.stream().sorted().distinct().collect(Collectors.toList());
            return result;
        }
    }
}
